package com.health.trans.config.dataSource;

import com.health.trans.util.EntityOperations;
import lombok.Getter;
import org.apache.commons.lang.WordUtils;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder;
import org.springframework.context.ApplicationContext;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.stereotype.Component;
import org.springframework.transaction.PlatformTransactionManager;

import javax.persistence.EntityManager;
import javax.sql.DataSource;
import java.util.Map;

/**
 * @author nqlz
 */
@Component
public abstract class AbstractBsDts {
    @Getter
    protected final String dataSourceName;
    @Getter
    protected DataSource dataSource;

    @Getter
    protected LocalContainerEntityManagerFactoryBean entityManagerFactory;
    @Getter
    protected PlatformTransactionManager transactionManager;
    @Getter
    protected EntityManager entityManager;

    protected AbstractBsDts(String dataSourceName, DataSource dataSource) {
        this.dataSourceName = dataSourceName;
        this.dataSource = dataSource;
    }


    public void initDs(ApplicationContext applicationContext, ConfigurableListableBeanFactory beanFactory, EntityManagerFactoryBuilder builder, Map<String, Object> vendorProperties){
        String[] packages = EntityOperations.packageNames.toArray(new String[0]);
        LocalContainerEntityManagerFactoryBean lf = builder
                .dataSource(dataSource)
                .properties(vendorProperties)
                .packages(packages)
                .persistenceUnit(dataSourceName)
                .properties(vendorProperties)
                .build();

        entityManagerFactory = (LocalContainerEntityManagerFactoryBean) applicationContext.getAutowireCapableBeanFactory().configureBean(lf, "entityManagerFactory");

        beanFactory.registerSingleton(WordUtils.uncapitalize(dataSourceName + "EntityManagerFactory"), getEntityManagerFactory());
        beanFactory.registerSingleton(WordUtils.uncapitalize(dataSourceName + "EntityManager"), entityManager());
        beanFactory.registerSingleton(WordUtils.uncapitalize(dataSourceName + "TransactionManager"), transactionManager());
        beanFactory.registerSingleton("bsDtSource" + dataSourceName, this);
    }

    protected EntityManager entityManager() {
        return entityManager = entityManagerFactory.getObject().createEntityManager();
    }

    protected PlatformTransactionManager transactionManager() {
        return transactionManager = new JpaTransactionManager(entityManagerFactory.getObject());
    }

}
